package com.ning.ems.service.impl;

import com.ning.ems.dao.UserDao;
import com.ning.ems.dto.UserCheckPassDto;
import com.ning.ems.dto.UserListDto;
import com.ning.ems.entity.User;
import com.ning.ems.exception.ServiceException;
import com.ning.ems.service.UserService;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.stream.Collectors;

import static com.ning.ems.util.Util.zeroToNull;

/**
 * @author Ning 242741154@qq.com
 * @date 2020/3/7 18:27
 */
@Service
@CacheConfig(cacheNames = "user")
public class UserServiceImpl implements UserService {
    // CAN NOT HAVE ANY OTHER SERVICE
    private final UserDao userDao;

    public UserServiceImpl(UserDao userDao) {
        this.userDao = userDao;
    }

    @Override
    public List<User> list(UserListDto info) {
        final Integer type = zeroToNull(info.getType());
        final Integer page = info.getPage();
        final Integer pageSize = info.getPageSize();
        final int offset = (page - 1) * pageSize;
        return userDao
                .list(type, offset, pageSize)
                .stream()
                .peek(user -> user.setPassword(null))
                .collect(Collectors.toList());
    }

    @Override
    @Cacheable(cacheNames = "user", key = "'id-'+#id")
    public User get(Integer id) {
        User obj = userDao.get(id, null);
        if (obj != null) {
            obj.setPassword(null);
            return obj;
        } else return null;
    }

    @Override
    @Cacheable(cacheNames = "user", key = "'mob_num-'+#mobileNumber")
    public User get(String mobileNumber) {
        User obj = userDao.get(null, mobileNumber);
        if (obj != null) {
            obj.setPassword(null);
            return obj;
        } else return null;
    }

    @Override
    public boolean checkMobileNumber(String mobileNumber) {
        return get(mobileNumber) == null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public User signUp(User user) {
        final String mobileNumber = user.getMobileNumber();
        if (checkMobileNumber(mobileNumber)) {
            userDao.add(user);
            user = get(mobileNumber);
            if (user != null) {
                user.setPassword(null);
                return user;
            }
        }
        throw new ServiceException("该手机号码已被占用!");
    }

    @Override
    @CacheEvict(cacheNames = "user", key = "'id-'+#id")
    public boolean delete(Integer id) {
        final int rtn = userDao.delete(id);
        return rtn == 1;
    }

    @Override
    @CacheEvict(cacheNames = "user", key = "'id-'+#id")
    public boolean updateName(Integer id, String name) {
        final int rtn = userDao.updateName(id, name);
        return rtn == 1;
    }

    @Override
    @CacheEvict(cacheNames = "user", key = "'id-'+#id")
    public boolean updatePassword(Integer id, String password) {
        final int rtn = userDao.updatePassword(id, password);
        return rtn == 1;
    }

    @Override
    @CacheEvict(cacheNames = "user", key = "'id-'+#id")
    public boolean updateMobileNumber(Integer id, String mobileNumber) {
        if (!checkMobileNumber(mobileNumber)) {
            throw new ServiceException("该手机号码已被占用!");
        }
        final int rtn = userDao.updateMobileNumber(id, mobileNumber);
        return rtn == 1;
    }

    @Override
    @CacheEvict(cacheNames = "user", key = "'id-'+#id")
    public boolean updateType(Integer id, Integer type) {
        final int rtn = userDao.updateType(id, type);
        return rtn == 1;
    }

    @Override
    public boolean checkPass(UserCheckPassDto info) {
        User user = userDao.get(info.getId(), null);
        return user.getPassword().equals(info.getPassword());
    }

    @Override
    public User signIn(User user) {
        User obj = userDao.get(null, user.getMobileNumber());
        if (obj != null && obj.getPassword().equals(user.getPassword())) {
            obj.setPassword(null);
            return obj;
        }
        return null;
    }
}
